package icasue.reflect.handles.fields;

import lombok.SneakyThrows;
import icasue.reflect.handles.OAble;
import icasue.reflect.handles.classes.ClassO;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @Author: Qiao Hang
 * @CreateDate: 2020/12/3 下午6:57
 * @UpdateDate:
 * @Description:
 */
public class FieldO implements OAble {

    static {
        try {
            Class<?> loadHandleOperate = FieldO.class.getClassLoader().loadClass("icasue.reflect.handles.HandleSupplier");
            Method reFindLookUpMethod = loadHandleOperate.getDeclaredMethod("reFindLookUp", new Class[]{Class.class});
            reFindLookUpMethod.setAccessible(true);
            FieldO.lookup = (MethodHandles.Lookup)reFindLookUpMethod.invoke(null, ClassO.class);
        }catch (Throwable e){
            /**/
        }
    }

    static {
        findHandles();
    }

    public static MethodHandles.Lookup lookup;

    public static MethodHandle get;
    public static MethodHandle set;
    public static MethodHandle getterHandle;
    public static MethodHandle setterHandle;

    @SneakyThrows(Throwable.class)
    private static void findHandles() {
        get = lookup.findVirtual(Field.class,"get", MethodType.methodType(Object.class,Object.class));
        set = lookup.findVirtual(Field.class,"set", MethodType.methodType(void.class,Object.class,Object.class));
        getterHandle = lookup.findVirtual(MethodHandles.Lookup.class,"unreflectGetter", MethodType.methodType(MethodHandle.class,Field.class));
        setterHandle = lookup.findVirtual(MethodHandles.Lookup.class,"unreflectSetter", MethodType.methodType(MethodHandle.class,Field.class));
    }
}
